<script setup lang="ts">
import { ref, watch, computed } from 'vue'
import type { PropType, Ref } from 'vue'
import type { CascaderValue } from 'element-plus'
import { filterRecursively, mapRecursively } from '@/utils/array-recursion'
import { loadPagePathTree, type PagePath } from './menu-scan-local'

// props
const props = defineProps({
  formRef: {
    type: Function as PropType<(el: any) => void>
  },
  modelValue: {
    type: Object as PropType<Record<string, any>>,
    default: () => { }
  },
  menuOptions: {
    type: Array as PropType<Record<string, any>[]>,
    default: () => []
  },
  useFor: {
    type: String as PropType<'add' | 'addSub' | 'edit'>,
    default: 'add'
  }
})

const emit = defineEmits<{
  (e: 'update:modelValue', model: any): void
}>()

const model: Ref<Record<string, any>> = ref(props.modelValue)
const pathMap: Ref<Record<string, PagePath>> = ref({})
const pageOptions: Ref<any[]> = ref([])

// on create
loadPagePathTree().then(([pathTree, _pathMap]) => {
  pageOptions.value = mapRecursively(pathTree, (pagePath) => {
    return {
      value: pagePath.path,
      label: pagePath.path,
      title: pagePath.title,
      children: pagePath.children
    }
  })
  pathMap.value = _pathMap
})



const parentMenuOptions = computed(() => {
  const options = filterRecursively(props.menuOptions, (menuItem) => menuItem.type == 'Directory')

  return mapRecursively(options, ({ value, label, type, children }) => {
    let option: Record<string, any>
    if (Array.isArray(children) && children.length == 0) {
      option = { value, label, type }
    } else {
      option = { value, label, type, children }
    }
    option.disabled = value == model.value.id
    return option
  })
})

watch(model, (v, ov) => {
  emit('update:modelValue', v)
})

function onPagePathChange(pagePath: CascaderValue): any {
  const page = pathMap.value[pagePath as string]
  model.value.permission = page?.permission
}
</script>

<template>
  <el-form v-if="model" :ref="formRef" :model="model" label-position="right" label-width="85px">
    <el-row>
      <el-col :span="12">
        <el-form-item label="上级菜单" prop="parentId">
          <el-cascader v-model="model.parentId" placeholder="请选择上级菜单" :options="parentMenuOptions" :props="{
            emitPath: false,
            checkStrictly: true
          }" :disabled="useFor == 'addSub'" clearable filterable style="width: 100%"></el-cascader>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="菜单名称" prop="name" required>
          <el-input v-model="model.name" placeholder="请输入菜单名称" maxlength="30" />
        </el-form-item>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="12">
        <el-form-item label="菜单类型" prop="type" required>
          <el-select v-model="model.type" :disabled="typeof model.id != 'undefined'" placeholder="请选择菜单类型"
            style="width: 100%">
            <el-option label="目录" value="Directory" :disabled="useFor == 'edit'"> </el-option>
            <el-option label="页面" value="Page" :disabled="useFor == 'edit' && model.type == 'Directory'"> </el-option>
            <el-option label="外部链接" value="ExternalLink" :disabled="useFor == 'edit' && model.type == 'Directory'">
            </el-option>
          </el-select>
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="图标" prop="icon">
          <el-input v-model="model.icon" placeholder="请输入图标" maxlength="50" clearable />
        </el-form-item>
      </el-col>
    </el-row>
    <el-row v-if="model.type == 'Page'">
      <el-col :span="12">
        <el-form-item label="页面路径" prop="pagePath" required>
          <el-cascader v-if="model.groupCode == 'local'" v-model="model.pagePath" placeholder="请输入页面路径"
            :options="pageOptions" :props="{
              emitPath: false
            }" :show-all-levels="false" filterable style="width: 100%" @change="onPagePathChange">
            <template #default="{ data }">
              <el-row type="flex" justify="space-between">
                <el-col :span="12" style="text-align: left">
                  <span>{{ data.value }} </span>
                </el-col>
                <el-col :span="12" style="text-align: right">
                  <el-tag v-if="data.title" type="info" size="small">{{ data.title }}</el-tag>
                </el-col>
              </el-row>
            </template>
          </el-cascader>
          <el-input v-else v-model="model.pagePath" placeholder="请输入页面路径" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="页面标题" prop="title" required>
          <el-input v-model="model.title" placeholder="请输入菜单标题" maxlength="30" />
        </el-form-item>
      </el-col>
    </el-row>
    <el-row>
      <el-col :span="12">
        <el-form-item v-if="model.type != 'ExternalLink'" label="请求路径" prop="path" required>
          <el-input v-model="model.path" placeholder="请输入请求路径" />
        </el-form-item>
        <el-form-item v-else-if="model.type == 'ExternalLink'" label="网络地址" prop="url" required>
          <el-input v-model="model.url" placeholder="请输入网址" />
        </el-form-item>
      </el-col>

      <el-col v-if="model.type != 'Directory'" :span="12">
        <el-form-item label="权限标识" prop="permission">
          <el-input v-model="model.permission" :disabled="model.type == 'Page'" placeholder="请输入权限标识" maxlength="100" />
        </el-form-item>
      </el-col>
      <el-col v-if="model.type != 'Directory'" :span="12">
        <el-form-item label="是否隐藏" prop="hidden">
          <el-switch v-model="model.hidden" />
        </el-form-item>
      </el-col>
      <el-col v-if="model.type != 'Directory'" :span="12">
        <el-form-item label="是否固定" prop="affix">
          <el-switch v-model="model.affix" />
        </el-form-item>
      </el-col>
      <el-col :span="12">
        <el-form-item label="排序号" required>
          <el-input v-model="model.sequence" type="number" :min="0" placeholder="请输入排序号"></el-input>
        </el-form-item>
      </el-col>
    </el-row>
  </el-form>
</template>
